package com.xw.userService.utils;


import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

/**
 * Date 工具类
 * 
 * @author xiaozejun 2016.07.06
 * @version 1.0 20160706 admin 新增
 */
public class DateUtil {
//	private static final Logger LOG = LoggerFactory.getLogger(DateUtil.class);
	/** 定义默认格式化时间格式 **/
	public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	/** 定义默认格式化日期 **/
	public static final String DATE_FORMAT = "yyyyMMdd";
	/** 默认格式化日期 **/
	public static final String DATE_FORMAT1 = "yyyy-MM-dd";
	
	/** 默认格式化时间 **/
	public static final String DATE_FORMATTIME = "HH:mm:ss";
	/**
	 * 获取当前系统时间
	 * 
	 * @return 系统时间
	 */
	public static Date getSystemDate() {
		return new Date();
	}

	/**
	 * 获取指定格式的当前系统时间
	 * 
	 * @param pattern
	 *            格式
	 * @return 格式化后的系统时间
	 */
	public static String getDateString(String pattern) {
		Date date = getSystemDate();
		DateFormat dfmt = new SimpleDateFormat(pattern);
		return dfmt.format(date);
	}

	/**
	 * 将指定时间按照指定格式进行格式化(Date类型)
	 * 
	 * @param date
	 *            指定时间
	 * @param pattern
	 *            指定格式
	 * @return 格式化后的指定时间
	 */
	public static String getDateString(Date date, String pattern) {
		DateFormat dfmt = new SimpleDateFormat(pattern);
		return dfmt.format(date);
	}

	/**
	 * 将yyyyMMdd8位字符串转换为日期
	 * 
	 * @param str
	 *            8为字符串
	 * @return 转换后的日期
	 */
	public static Date str2Date(String str) {
		Date date = null;
		if (StringUtils.isNotBlank(str)) {
			date = toDate(str, DATE_FORMAT1);
		}
		return date;
	}
	
	
	/**
	 * 将HH:mm:ss8位字符串转换为日期
	 * 
	 * @param str
	 *            8为字符串
	 * @return 转换后的日期
	 */
	public static Date str3Date(String str) {
		Date date = null;
		if (StringUtils.isNotBlank(str)) {
			date = toDate(str, DATE_FORMATTIME);
		}
		return date;
	}

	/**
	 * 将指定时间按照指定格式进行格式化(String类型)
	 * 
	 * @param dateStr
	 *            指定时间
	 * @param format
	 *            指定格式
	 * @return 格式化后的指定时间
	 */
	public static Date toDate(String dateStr, String format) {
		DateFormat df = new SimpleDateFormat(format);
		try {
			java.util.Date date = df.parse(dateStr);
			Date d = new Date(date.getTime());
			return d;
		} catch (ParseException e) {
			throw new RuntimeException("转换日期字符串时出错！", e);
		}
	}

	/**
	 * 将指定时间按照默认的格式进行格式化yyyy-MM-dd HH:mm:ss
	 * 
	 * @param date
	 *            日期
	 * @return 格式化的字符串日期
	 */
	public static String date2String(Date date) {
		SimpleDateFormat sdfmt = new SimpleDateFormat(DATETIME_FORMAT);
		return date != null ? sdfmt.format(date) : "";
	}
	
	/**
	 * 将指定时间按照默认的格式进行格式化yyyyMMdd
	 * 
	 * @param date
	 *            日期
	 * @return 格式化的字符串日期
	 */
	public static String date1String(Date date) {
		SimpleDateFormat sdfmt = new SimpleDateFormat(DATE_FORMAT);
		return date != null ? sdfmt.format(date) : "";
	}

	/**
	 * 获取当前日期N天后的日期
	 * 
	 * @param pattern
	 *            默认格式
	 * @param i
	 *            N天后 负数则为N天前
	 * @return 返回计算后的日期
	 */
	public static String getDateString(String pattern, int i) {
		DateFormat dfmt = new SimpleDateFormat(pattern);
		Date date = getSystemDate();
		date = DateUtils.addDays(date, i);
		return dfmt.format(date);
	}
	
	/**
	 * 获取当前日期N天后的日期
	 * 
	 * @param date
	 *            日期
	 * @param pattern
	 *            默认格式
	 * @param i
	 *            N天后 负数则为N天前
	 * @return 返回计算后的日期
	 */
	public static String getDateString(Date date,String pattern, int i) {
		DateFormat dfmt = new SimpleDateFormat(pattern);
		if(date == null){
			date = getSystemDate();
		}
		date = DateUtils.addDays(date, i);
		return dfmt.format(date);
	}
	
	/**
	 * 获取七天时间
	 * @param pattern 参数
	 * @param i 参数
	 * @return  List 参数
	 */
	public static List<String> getSevenDate(String pattern, int i) {
		List<String> list = new ArrayList<String>();
		DateFormat dfmt = new SimpleDateFormat(pattern);
		Date date = getSystemDate();
		for (int j = 0; j < i; j++) {
			list.add(dfmt.format(DateUtils.addDays(date, j)));
		}
		return list;
	}


	/**
	 * 计算year所有的周六、日
	 * 
	 * @param year
	 *            参数对象
	 * @return List<Date>
	 */
	public static List<Date> getHolidayDate(int year) {
		List<Date> dateDist = new ArrayList<Date>();
		Calendar calendar = new GregorianCalendar(year, 0, 1);
		int i = 1;
		while (calendar.get(Calendar.YEAR) < year + 1) {
			calendar.set(Calendar.WEEK_OF_YEAR, i++);
			calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			// 生成周日
			if (calendar.get(Calendar.YEAR) == year) {
				dateDist.add(calendar.getTime());
			}
			// 生成周六
			calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
			if (calendar.get(Calendar.YEAR) == year) {
				dateDist.add(calendar.getTime());
			}
		}

		return dateDist;
	}
	
	/**
	 * 获取两个日期之间的所有天
	 * @author lgz
	 * @param startDate 开始日
	 * @param endDate 截止日
	 * @return list 日期集合
	 */
	public static List<Date> getEveryDate(Date startDate, Date endDate){
		List<Date> list=new ArrayList<Date>();
		Calendar cal = Calendar.getInstance();
		cal.setTime(startDate);
		while(cal.getTime().compareTo(endDate)<0){
			 list.add(cal.getTime());
			 cal.add(Calendar.DAY_OF_MONTH,1);
		}
		if((cal.getTime().compareTo(endDate)==0)){
			  list.add(cal.getTime());
		}
		 return list;
	}
	
	/** 
     *  
     * 1 第一季度 2 第二季度 3 第三季度 4 第四季度 
     *  
     * @param date 日期
     * @return  第几季度
     */  
    public static int getSeason(Date date) {   
        int season = 0;    
        Calendar c = Calendar.getInstance();  
        c.setTime(date);  
        int month = c.get(Calendar.MONTH);  
        switch (month) {  
        case Calendar.JANUARY:  
        case Calendar.FEBRUARY:  
        case Calendar.MARCH:  
            season = 1;  
            break;  
        case Calendar.APRIL:  
        case Calendar.MAY:  
        case Calendar.JUNE:  
            season = 2;  
            break;  
        case Calendar.JULY:  
        case Calendar.AUGUST:  
        case Calendar.SEPTEMBER:  
            season = 3;  
            break;  
        case Calendar.OCTOBER:  
        case Calendar.NOVEMBER:  
        case Calendar.DECEMBER:  
            season = 4;  
            break;  
        default:  
            break;  
        }  
        return season;  
    }
	
	/**
	 * 将yyyyMMdd8位字符串转换为日期
	 * 
	 * @param str
	 *            8为字符串
	 * @return 转换后的日期
	 */
	public static Date str1Date(String str) {
		Date date = null;
		if (StringUtils.isNotBlank(str)) {
			date = toDate(str, DATE_FORMAT);
		}
		return date;
	}  

	/**
	 * 获取日期的前/后N个月的日期
	 * @param date 日期
	 * @param n 负数为向前/整数为向后的天数 
	 * @return Date
	 */
	public static Date getNextMonthDay(Date date,int n){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, n);
		return cal.getTime();
	}
	
	/**
	 * 获取当前日期N天后的日期
	 * @param date 日期
	 * @param n 负数为向前/整数为向后的天数 
	 * @return date
	 */
	public static Date getNextDay(Date date,int n){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DATE, n);
		return cal.getTime();
	}
	
	/**
	 * 获取当前日期的月末
	 * @param date 日期
	 * @return Date 月末
	 */
	public static Date getMonthMaxDay(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
		return cal.getTime();
	}
	
	/**
     * 获取当年的第一天
     * @param date 日期
     * @return Date
     */
    public static Date getCurrYearFirst(Date date){
        Calendar cal=Calendar.getInstance();  
        cal.setTime(date);
        int currentYear = cal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }
    
    /**
     * 获取当年的最后一天
     * @param date 日期
     * @return Date
     */
    public static Date getCurrYearLast(Date date){
        Calendar calendar=Calendar.getInstance();  
        calendar.setTime(date);
        int currentYear = calendar.get(Calendar.YEAR);
        return getYearLast(currentYear);
    }
    
	/**
     * 获取某年第一天日期
     * @param year 年份
     * @return Date
     */
    public static Date getYearFirst(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }
     
    /**
     * 获取某年最后一天日期
     * @param year 年份
     * @return Date
     */
    public static Date getYearLast(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }
    
    /**
     * 获取两个日期相减得到天数
     * @param endDate 结束日
     * @param beginDate 开始日
     * @return Long 
     */
    public static Long getDays(Date endDate,Date beginDate){
    	  return (endDate.getTime()-beginDate.getTime())/(24*60*60*1000);  
    }
    
    /**
     * 获取两个日期相减得到的月数(带小数)
     * @param endDate 结束日
     * @param beginDate 开始日
     * @return int 
     */
    public static float getMonths(Date endDate,Date beginDate){
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(endDate);
    	int end=calendar.get(Calendar.MONTH);
    	Calendar cal=Calendar.getInstance();
    	cal.setTime(beginDate);
    	int start=cal.get(Calendar.MONTH);
    	//相差月数整数部分
    	int n=end-start;
    	//相差月数=整数部分+小数部分
    	Date nextMonthDay=getNextMonthDay(beginDate, n);
    	float ss=n;
    	if(nextMonthDay.compareTo(endDate)<0){
    		float part= getDays(endDate,nextMonthDay);
    		float all=getDayOfMonth(endDate);
    		ss=n+part/all; 
    	}
    
    	return ss; 
    }
    /**
     * 获取当前日期所在月的天数
     * @param date 日期
     * @return int 天数
     */
    public static int getDayOfMonth(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int day=calendar.getActualMaximum(Calendar.DATE);
		return day;
	}
    
	/**
	 * 获取当前日期N天后的日期
	 * 
	 * @param date
	 *            当前日期
	 * @param index
	 *            N天后的日期
	 * @return Date
	 */
	public static Date toDate(Date date, int index) {
		return DateUtil.toDate(DateUtil.getDateString(date, "yyyy-MM-dd", index), "yyyy-MM-dd");
	}
    

}
